﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Hosting;
using EPiServer;
using FortuneCookie.EPiServer.SearchAndReplace.Configuration;
using FortuneCookie.EPiServer.SearchAndReplace.Data;
using EPiServer.PlugIn;

namespace FortuneCookie.EPiServer.SearchAndReplace
{
    /// <summary>
    /// Register resource class
    /// </summary>
    public class RegisterResources : PlugInAttribute
    {

        #region Members

        private static bool _executed;

        #endregion Methods

        #region Static methods

        /// <summary>
        /// Initialises VPP mappings and creates dependent tables
        /// </summary>
        public static void Start()
        {
            RegisterVppResources();

            if (!ConfigurationHelper.CreateTablesAndStoredProcedures)
                return;

            CreateDependentTables();
        }

        /// <summary>
        /// Registers Vpp resources
        /// </summary>
        private static void RegisterVppResources()
        {
            if (HttpContext.Current == null)
                return;

            HostingEnvironment.RegisterVirtualPathProvider(new ResourcePathProvider("/Templates/Plugins/SearchAndReplace.ascx", "FortuneCookie.EPiServer.SearchAndReplace.Templates.Plugins.SearchAndReplace.ascx", false));
            HostingEnvironment.RegisterVirtualPathProvider(new ResourcePathProvider("/util/FortuneCookieSearchAndReplace.aspx", "FortuneCookie.EPiServer.SearchAndReplace.Templates.Plugins.SearchAndReplace.aspx", false));

            string cmsPath = UriSupport.ResolveUrlFromUIBySettings(string.Empty);
            string epiServerCmsFilePath = GetEPiServerCmsPath();

            if (!string.IsNullOrEmpty(epiServerCmsFilePath))
                HostingEnvironment.RegisterVirtualPathProvider(new ResourcePathProvider(cmsPath + "edit/PageCompare/Plugin/PageComparePlugin.ascx", epiServerCmsFilePath + @"edit\PageCompare\Plugin\PageComparePlugin.ascx", true));
        }

        /// <summary>
        /// Creates dependent sql tables
        /// </summary>
        private static void CreateDependentTables()
        {
            if (!ConfigurationHelper.CreateTablesAndStoredProcedures)
                return;

            SqlDataHelper dataHelper = new SqlDataHelper();
            bool tablesAndProceduresExist = dataHelper.TablesExist();

            if (tablesAndProceduresExist)
                return;

            if (_executed)
                return;

            _executed = true;
            List<string> commands = GetScriptCommands("FortuneCookie.EPiServer.SearchAndReplace.SQLScripts.1.SearchandReplaceTableCreation.Sql");
            commands.AddRange(GetScriptCommands("FortuneCookie.EPiServer.SearchAndReplace.SQLScripts.2.SearchandReplaceStoredProcedureCreation.Sql"));

            foreach (string command in commands)
                dataHelper.CreateObjects(command);
        }

        /// <summary>
        /// Gets the episerver cms path
        /// </summary>
        /// <returns></returns>
        private static string GetEPiServerCmsPath()
        {
            string epiServerCmsPath = string.Empty;

            foreach (ProviderSettings provider in global::EPiServer.Configuration.EPiServerSection.Instance.VirtualPathSettings.Providers)
            {
                if (!string.Equals(provider.Name, "UI", StringComparison.OrdinalIgnoreCase))
                    continue;

                epiServerCmsPath = provider.Parameters["physicalPath"].Trim();

                if (!epiServerCmsPath.EndsWith("\\"))
                    epiServerCmsPath += "\\";

                return epiServerCmsPath;
            }

            return epiServerCmsPath;
        }

        /// <summary>
        /// Gets sql script command from an embedded sql script resource
        /// </summary>
        /// <param name="manifestName"></param>
        /// <returns></returns>
        private static List<string> GetScriptCommands(string manifestName)
        {
            string script;

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(manifestName))
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    script = streamReader.ReadToEnd();
                }
            }

            script = script.Replace("GO", "~");
            return script.Split(new[] {'~'}, StringSplitOptions.RemoveEmptyEntries).ToList();
        }

        #endregion Static methods

    }
}
